package model

import (
	"database/sql"
	"encoding/json"
	"github.com/valyala/fasthttp"
	"math"
	"strconv"
	"strings"
	"time"
)

// 获取月份的最后一天 month 格式：2023-11
func GetMonthStartAndEnd(month string) string {
	v := strings.Split(month, "-")
	if len(v) < 2 {
		month = time.Now().Format("2006-01")
		v = strings.Split(month, "-")
	}
	myYear := v[0]
	myMonth := v[1]
	// 数字月份必须前置补零
	yInt, _ := strconv.Atoi(myYear)
	timeLayout := "2006-01-02 15:04:05"
	loc, _ := time.LoadLocation("Local")
	theTime, _ := time.ParseInLocation(timeLayout, myYear+"-"+myMonth+"-01 00:00:00", loc)
	newMonth := theTime.Month()
	result := time.Date(yInt, newMonth+1, 0, 0, 0, 0, 0, time.Local).Format("2006-01-02")
	return result
}

func ReportApiFeeList(param ReportApiFeeParam, ctx *fasthttp.RequestCtx) (ReportApiFeeRetData, error) {
	data := ReportApiFeeRetData{}

	monthDate := param.MonthDate
	if param.MonthDate == "" {
		monthDate = time.Now().Format("2006-01")
	}
	fromDate := monthDate + "-01"
	toDate := GetMonthStartAndEnd(monthDate)

	loginUser := GetLoginUser(ctx)

	if loginUser.Operator != "" {
		if param.IsBusiness == 1 {
			//渠道查询业务员对账表
			data = reportBusinessApiFeeList(param, fromDate, toDate, " and a.operator_id="+loginUser.Operator)
		} else {
			OperatorInfo, _ := GetOperatorInfoById(loginUser.Operator)
			if OperatorInfo.ExtendOperator != "" {
				data = reportOperatorApiFeeList(param, fromDate, toDate, " and id in("+OperatorInfo.ExtendOperator+","+loginUser.Operator+")")
			} else {
				data = reportOperatorApiFeeList(param, fromDate, toDate, " and id="+loginUser.Operator)
			}

		}
	} else if loginUser.Businsess != "" {
		data = reportBusinessApiFeeList(param, fromDate, toDate, "and a.id in("+GetBusinessTeam(loginUser.Businsess, loginUser.Businsess)+")")
	} else {
		if param.IsOperator == 1 {
			//总后台查询渠道对账表
			data = reportOperatorApiFeeList(param, fromDate, toDate, "")
		}
		if param.IsBusiness == 1 {
			//总后台查询业务员对账表
			data = reportBusinessApiFeeList(param, fromDate, toDate, "")
		}
	}

	return data, nil
}

// 渠道对账表
func reportOperatorApiFeeList(param ReportApiFeeParam, fromDate string, toDate string, queryRange string) ReportApiFeeRetData {

	data := ReportApiFeeRetData{}
	where1, where2, where3, where4 := "1=1", "1=1", "1=1", "1=1"
	if param.OperatorName != "" {
		OperatorInfo, _ := GetOperatorInfoByUsername(param.OperatorName)
		where1 += " and id=" + OperatorInfo.Id
		where2 += " and operator_id=" + OperatorInfo.Id
		where3 += " and operator_id=" + OperatorInfo.Id
		where4 += " and operator_id=" + OperatorInfo.Id
	}
	if param.OperatorId != "" {
		where1 += " and id=" + param.OperatorId
		where2 += " and operator_id=" + param.OperatorId
		where3 += " and operator_id=" + param.OperatorId
		where4 += " and operator_id=" + param.OperatorId
	}
	// 1.获取待查询的渠道列表
	where1 += queryRange
	offset := (param.Page - 1) * param.PageSize
	sql1 := "select  id as operator_id,operator_name,recharge_fee as deposit_fee,withdraw_fee,api_fee,game_fee_rate from tbl_operator_info where " + where1 + " order by id asc limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)
	//fmt.Println(sql1)
	// 2.获取各渠道当月的 各平台盈亏，计算api费用
	where2 += " and created_at>='" + fromDate + "' and created_at<='" + toDate + "'"
	sql2 := "select operator_id,platform_id,ifnull(sum(running),0) running,ifnull(sum(game_winlost),0) game_winlost,ifnull(sum(game_tax),0) game_tax,ifnull(sum(sandbag_running),0) sandbag_running,ifnull(sum(sandbag_game_winlost),0) sandbag_game_winlost from tbl_report_game_daily where " + where2 + " and  business_id=0 and operator_id>0 group by operator_id,platform_id"

	// 3.获取各渠道当月的 充值，提现等数据
	where3 += " and created_at>='" + fromDate + "' and created_at<='" + toDate + "'"
	sql3 := "select operator_id,ifnull(sum(deposit),0) deposit,ifnull(sum(withdraw),0) withdraw from tbl_report_daily where " + where3 + " and business_id=0 and operator_id>0 group by operator_id"

	// 4.获取各渠道当月的 未充提现
	where4 += " and a.created_at>='" + fromDate + "' and a.created_at<='" + toDate + "'"
	sql4 := "select operator_id,sum(a.withdraw) undeposit_withdraw from tbl_report_user_daily as a join tbl_member_base as b on a.uid=b.uid join tbl_member_accu as c on c.uid=a.uid  where c.deposit=0 and " + where4 + " group by operator_id"

	err := meta.MerchantDB.Get(&data.T, "select count(1) from tbl_operator_info where "+where1)
	if err != nil && err != sql.ErrNoRows {
		return data
	}

	err = meta.MerchantDB.Select(&data.D, sql1)
	if err != nil && err != sql.ErrNoRows {

		return data
	}

	//游戏数据
	gameReport := []ReportGameDailyData{}
	err = meta.MerchantDB.Select(&gameReport, sql2)
	if err != nil && err != sql.ErrNoRows {

		return data
	}
	gameReportMap := map[string]float64{}
	for _, value := range gameReport {
		platform := int64(value.PlatformId/10) * 10
		gameReportMap[value.OperatorId+"-"+strconv.FormatInt(platform, 10)] += value.GameWinlost - value.Running + value.SandbagRunning - value.SandbagGameWinlost
	}
	//充值提现数据
	monthReport := []ReportDailyData{}
	err = meta.MerchantDB.Select(&monthReport, sql3)
	if err != nil && err != sql.ErrNoRows {

		return data
	}
	monthReportMap := map[string]ReportDailyData{}
	for _, value := range monthReport {
		monthReportMap[value.OperatorId] = value
	}

	//未充提现
	undepositWithdraw := []ReportApiFeeData{}
	err = meta.MerchantDB.Select(&undepositWithdraw, sql4)

	if err != nil && err != sql.ErrNoRows {

		return data
	}
	undepositWithdrawMap := map[string]float64{}
	for _, value := range undepositWithdraw {
		undepositWithdrawMap[value.OperatorId] += value.UndepositWithdraw
	}
	//构造返回数据
	for key, value := range data.D {

		apiFeeRate := map[string]float64{}
		json.Unmarshal([]byte(value.ApiFee), &apiFeeRate)
		OperatorId := value.OperatorId
		totalApiFee := 0.0
		for gameId, rate := range apiFeeRate {
			sigleApi := 0.0
			if value.GameFeeRate < 0 {
				sigleApi = gameReportMap[OperatorId+"-"+gameId] * rate
			} else {
				sigleApi = gameReportMap[OperatorId+"-"+gameId] * value.GameFeeRate
			}

			if sigleApi < 0 {
				totalApiFee += sigleApi
			}
			if gameId == "1200" {
				data.D[key].Fagamimg = -gameReportMap[OperatorId+"-"+gameId]
				//if sigleApi < 0 {
				//	data.D[key].Fagamimg = math.Abs(sigleApi)
				//}
			}
		}
		totalApiFee = math.Abs(totalApiFee)
		data.D[key].ApiFee = strconv.FormatFloat(totalApiFee, 'f', 2, 64)
		data.D[key].Deposit = monthReportMap[OperatorId].Deposit
		data.D[key].DepositFee = monthReportMap[OperatorId].Deposit * value.DepositFee
		data.D[key].Withdraw = monthReportMap[OperatorId].Withdraw
		data.D[key].WithdrawFee = monthReportMap[OperatorId].Withdraw * value.WithdrawFee
		data.D[key].UndepositWithdraw = undepositWithdrawMap[OperatorId]
		data.D[key].TotalProfit = data.D[key].Deposit - data.D[key].DepositFee - data.D[key].Withdraw - data.D[key].WithdrawFee - totalApiFee
	}
	return data
}

// 业务员对账表
func reportBusinessApiFeeList(param ReportApiFeeParam, fromDate string, toDate string, queryRange string) ReportApiFeeRetData {
	data := ReportApiFeeRetData{}
	where1, where2, where3 := "1=1", "1=1", "1=1"

	if param.OperatorId != "" {
		where1 += " and a.operator_id=" + param.OperatorId
		where2 += " and operator_id=" + param.OperatorId
		where3 += " and operator_id=" + param.OperatorId

	}
	if param.BusinessId != "" {
		where1 += " and a.id=" + param.BusinessId
		where2 += " and business_id=" + param.BusinessId
		where3 += " and business_id=" + param.BusinessId

	}
	// 1.获取待查询的业务员列表
	where1 += queryRange
	offset := (param.Page - 1) * param.PageSize
	//sql1 := "select a.id as business_id,a.account_name business_name,a.operator_id,b.operator_name,b.recharge_fee as deposit_fee,b.withdraw_fee,api_fee from tbl_business_info a inner join  tbl_operator_info as b on b.id=a.operator_id where " + where1 + " order by a.id asc limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)

	//使用业务员自己的费率
	sql1 := "select a.id as business_id,a.account_name business_name,a.operator_id,b.operator_name,a.recharge_fee as deposit_fee,a.withdraw_fee,a.api_fee as api_fee,a.game_fee_rate as game_fee_rate from tbl_business_info a inner join  tbl_operator_info as b on b.id=a.operator_id where " + where1 + " order by a.id asc limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)

	// 2.获取各渠道当月的 各平台盈亏，计算api费用
	where2 += " and created_at>='" + fromDate + "' and created_at<='" + toDate + "'"
	sql2 := "select business_id,platform_id,ifnull(sum(running),0) running,ifnull(sum(game_winlost),0) game_winlost,ifnull(sum(game_tax),0) game_tax,ifnull(sum(sandbag_running),0) sandbag_running,ifnull(sum(sandbag_game_winlost),0) sandbag_game_winlost from tbl_report_game_daily where " + where2 + " and  business_id>0 group by business_id,platform_id"

	// 3.获取各渠道当月的 充值，提现等数据
	where3 += " and created_at>='" + fromDate + "' and created_at<='" + toDate + "'"
	sql3 := "select business_id,ifnull(sum(deposit),0) deposit,ifnull(sum(withdraw),0) withdraw from tbl_report_daily where " + where3 + " and business_id>0  group by business_id"

	err := meta.MerchantDB.Get(&data.T, "select count(1) from tbl_business_info a inner join  tbl_operator_info as b on b.id=a.operator_id where "+where1)
	if err != nil && err != sql.ErrNoRows {
		return data
	}
	err = meta.MerchantDB.Select(&data.D, sql1)
	if err != nil && err != sql.ErrNoRows {

		return data
	}
	//游戏数据
	gameReport := []ReportGameDailyData{}
	err = meta.MerchantDB.Select(&gameReport, sql2)
	if err != nil && err != sql.ErrNoRows {

		return data
	}
	gameReportMap := map[string]float64{}
	for _, value := range gameReport {
		platform := int64(value.PlatformId/10) * 10
		gameReportMap[value.BusinessId+"-"+strconv.FormatInt(platform, 10)] += value.GameWinlost - value.Running + value.SandbagRunning - value.SandbagGameWinlost
	}
	//充值提现数据
	monthReport := []ReportDailyData{}
	err = meta.MerchantDB.Select(&monthReport, sql3)
	if err != nil && err != sql.ErrNoRows {

		return data
	}
	monthReportMap := map[string]ReportDailyData{}
	for _, value := range monthReport {
		monthReportMap[value.BusinessId] = value
	}

	//构造返回数据
	for key, value := range data.D {
		apiFeeRate := map[string]float64{}
		json.Unmarshal([]byte(value.ApiFee), &apiFeeRate)
		BusinessId := value.BusinessId
		totalApiFee := 0.0
		for gameId, rate := range apiFeeRate {
			sigleApi := 0.0
			if value.GameFeeRate < 0 {
				sigleApi = gameReportMap[BusinessId+"-"+gameId] * rate
			} else {
				sigleApi = gameReportMap[BusinessId+"-"+gameId] * value.GameFeeRate
			}
			if sigleApi < 0 {
				totalApiFee += sigleApi
			}
			if gameId == "1200" {
				data.D[key].Fagamimg = -gameReportMap[BusinessId+"-"+gameId]
			}
		}
		totalApiFee = math.Abs(totalApiFee)
		data.D[key].ApiFee = strconv.FormatFloat(totalApiFee, 'f', 2, 64)
		data.D[key].Deposit = monthReportMap[BusinessId].Deposit
		data.D[key].DepositFee = monthReportMap[BusinessId].Deposit * value.DepositFee
		data.D[key].Withdraw = monthReportMap[BusinessId].Withdraw
		WithdrawFee := monthReportMap[BusinessId].Withdraw * value.WithdrawFee
		data.D[key].WithdrawFee = math.Round(WithdrawFee*100) / 100
		total_profit := data.D[key].Deposit - data.D[key].DepositFee - data.D[key].Withdraw - data.D[key].WithdrawFee - totalApiFee
		data.D[key].TotalProfit = math.Round(total_profit*100) / 100
	}
	return data
}
